home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
Libraries
/
DCLAP 6d
/
dclap6d
/
SeqPups
/
appsrc
/
drawtree.src
/
drawgram.c
next >
Wrap
Text File
|
1996-07-05
|
26KB
|
1,020 lines
#include "drawgraphics.h"
/* Version 3.52c. Copyright (c) 1986-1993 by Joseph Felsenstein and
Christopher A. Meacham. Additional code written by Hisashi Horino,
Sean Lamont, Andrew Keefe, and Akiko Fuseki.
Permission is granted to copy, distribute, and modify this
program provided that (1) this copyright message is not removed
and (2) no fee is charged for this program. */
FILE *treefile, *plotfile;
char pltfilename[100];
long ntips, nextnode, strpwide, strpdeep,strpdiv,
strptop, strpbottom, payge, numlines;
boolean preview, previewing, dotmatrix,
haslengths, uselengths, empty, rescaled;
double xmargin, ymargin, topoflabels, rightoflabels, leftoflabels,
tipspacing,maxheight, scale, xscale, yscale, xoffset, yoffset,
nodespace, stemlength, treedepth, xnow, ynow, xunitspercm, yunitspercm,
xsize, ysize, xcorner, ycorner, labelheight,labelrotation,expand, rooty,
bscale;
striptype stripe;
plottertype plotter, oldplotter, previewer;
growth grows;
treestyle style;
node *root;
node *nodep[maxnodes];
fonttype font;
long filesize;
Char ch;
char fontname[64];
enum { yes, no} penchange,oldpenchange;
static enum { weighted, intermediate, centered, inner, vshaped} nodeposition;
openfile(fp,filename,mode,application,perm)
FILE **fp;
char *filename;
char *mode;
char *application;
char *perm;
{
FILE *of;
char file[100];
strcpy(file,filename);
while (1){
of = fopen(file,mode);
if (of)
break;
else {
switch (*mode){
case 'r':
printf("%s: can't read %s\n",application,file);
file[0] = '\0';
while (file[0] =='\0'){
printf("Please enter a new filename>");
gets(file);}
break;
case 'w':
printf("%s: can't write %s\n",application,file);
file[0] = '\0';
while (file[0] =='\0'){
printf("Please enter a new filename>");
gets(file);}
break;
}
}
}
*fp=of;
if (perm != NULL)
strcpy(perm,file);
}
void uppercase(ch)
Char *ch;
{ /* make ch upper-case */
*ch = (islower(*ch) ? toupper(*ch) : (*ch));
} /* uppercase */
void getch(c)
Char *c;
{ /* get next nonblank character */
do {
*c=getc(treefile); }
while ((*c == ' ')||(*c == '\n')||(*c == '\t'));
} /* getch */
Void processlength(p)
node *p;
{
long digit, ordzero;
double valyew, divisor;
boolean pointread, minusread;
ordzero = '0';
pointread = false;
minusread = false;
valyew = 0.0;
divisor = 1.0;
getch(&ch);
digit = ch - ordzero;
while (((unsigned long)digit <= 9) | (ch == '.') || (ch == '-')){
if (ch == '.') pointread = true;
else if (ch == '-') minusread = true;
else {
valyew = valyew * 10.0 + digit;
if (pointread)
divisor *= 10.0;
}
getch(&ch);
digit = ch - ordzero;
}
if (!minusread)
p->oldlen = valyew / divisor;
else
p->oldlen = 0.0;
/* processlength */
}
void addelement(p, q)
node **p, *q;
{
/* read in and add next part of tree, it will be node p
and will be hooked to pointer q */
node *pfirst;
long n;
boolean notlast;
nextnode++;
*p = (node *)Malloc((long)sizeof(node));
nodep[nextnode - 1] = *p;
if (ch == '(') {
(*p)->tip = false;
(*p)->tipsabove = 0;
pfirst = *p;
notlast = true;
while (notlast) {
(*p)->next = (node *)Malloc((long)sizeof(node));
*p = (*p)->next;
(*p)->tip = false;
getch(&ch);
addelement(&(*p)->back, *p);
pfirst->tipsabove += (*p)->back->tipsabove;
if (ch == ')') {
notlast = false;
do {
getch(&ch);
} while (ch != ':' && ch != ',' && ch != ')' && ch != '[' && ch != ';');
}
}
(*p)->next = pfirst;
*p = pfirst;
} else {
(*p)->tip = true;
(*p)->tipsabove = 1;
ntips++;
n = 1;
do {
if (ch == '_')
ch = ' ';
if (!ebcdic && (ch & 255) == 255)
ch = '\'';
if (!ebcdic && (ch & 255) > 175)
ch -= 48;
if (!ebcdic && (ch & (~127)) != 0)
ch -= 64;
if (n < maxnch)
(*p)->nayme[n - 1] = ch;
if (eoln(treefile)) {
fscanf(treefile, "%*[^\n]");
getc(treefile);
}
ch = getc(treefile);
n++;
} while (ch != ':' && ch != ',' && ch != ')');
if (n > maxnch)
n = maxnch + 1;
(*p)->naymlength = n - 1;
}
if (ch == ':')
processlength(*p);
else
haslengths = (haslengths && q == NULL);
(*p)->back = q;
} /* addelement */
void treeread()
{
/* read a tree from the treefile and set up nodes and pointers */
haslengths = true;
ntips = 0;
nextnode = 0;
getch(&ch);
addelement(&root, NULL);
fscanf(treefile, "%*[^\n]");
getc(treefile);
uselengths = haslengths;
} /* treeread */
void initialparms()
{
/* initialize parameters */
getplotter();
plotrparms();
if (dotmatrix)
numlines = (long)floor(yunitspercm * ysize + 0.5) / strpdeep;
xmargin = 0.08 * xsize;
ymargin = 0.08 * ysize;
xscale = xunitspercm;
yscale = yunitspercm;
style = cladogram;
grows = vertical;
labelrotation = 45.0;
nodespace = 3.0;
stemlength = 0.05;
treedepth = 0.5 / 0.95;
rescaled = true;
bscale = 1.0;
if (uselengths)
nodeposition = intermediate;
else
nodeposition = vshaped;
} /* initialparms */
long showparms()
{
long i;
long numtochange;
char input[32];
Char ch, ch2,trash;
putchar('\n');
if (previewer == tek)
printf("%c\f", escape);
else {
for (i = 1; i <= 24; i++)
putchar('\n');
}
printf("Here are the settings: \n\n");
printf(" (1) Tree grows: ");
printf((grows == vertical) ? "Vertically\n" : "Horizontally\n");
printf(" (2) Style of tree: %s\n",
(style == cladogram) ? "Cladogram" :
(style == phenogram) ? "Phenogram" :
(style == curvogram) ? "Curvogram" :
(style == eurogram) ? "Eurogram" : "Swoopogram");
printf(" (3) Use branch lengths: ");
if (haslengths) {
if (uselengths)
printf("Yes\n");
else
printf("No\n");
} else
printf("(no branch lengths available)\n");
printf(" (4) Angle of labels:");
if (labelrotation < 10.0)
printf("%5.1f\n", labelrotation);
else
printf("%6.1f\n", labelrotation);
if (plotter == ray) {
printf(" (5) Horizontal margins:%6.2f pixels\n", xmargin);
printf(" (5) Vertical margins:%6.2f pixels\n", ymargin);
} else {
printf(" (5) Horizontal margins:%6.2f cm\n", xmargin);
printf(" (5) Vertical margins:%6.2f cm\n", ymargin);
}
printf(" (6) Scale of branch length:");
if (rescaled)
printf(" Automatically rescaled\n");
else
printf(" Fixed:%6.2f cm per unit branch length\n", bscale);
printf(" (7) Depth/Breadth of tree:%6.2f\n", treedepth);
printf(" (8) Stem-length/tree-depth:%6.2f\n", stemlength);
printf(" (9) Character ht / tip space:%8.4f\n", 1.0 / nodespace);
printf("(10) Ancestral nodes: %s\n",
(nodeposition == weighted) ? "Weighted" :
(nodeposition == intermediate) ? "Intermediate" :
(nodeposition == centered) ? "Centered" :
(nodeposition == inner) ? "Inner" :
"So tree is V-shaped");
if (plotter == lw)
printf("(11) Font : %s\n",fontname);
printf("\n Do you want to accept these? (Yes or No)\n");
for (;;) {
printf(" Type Y or N or the number (1-%2ld) of the one to change:\n",
((plotter == lw) ? 11L : 10L));
gets(input);
uppercase(&input[0]);
numtochange = atoi(input);
ch = input[0];
if ((ch == 'Y' || ch == 'N') || (numtochange >= 1 && numtochange <= 11))
break;
}
return (ch == 'Y') ? -1 : numtochange;
} /* showparms */
void getparms(numtochange)
long numtochange;
{
/* get from user the relevant parameters for the plotter and diagram */
Char ch,trash;
boolean ok;
if (numtochange == 0) {
do {
printf(" Type the number of one that you want to change (1-%2ld):\n",
((plotter == lw) ? 11L : 10L));
scanf("%hd%*[^\n]", &numtochange);
trash=getchar();
} while (numtochange < 1 || numtochange > ((plotter == lw) ? 11 : 10));
}
switch (numtochange) {
case 1:
if (grows == vertical)
grows = horizontal;
else
grows = vertical;
break;
case 2:
printf("\nWhat style tree is this to be:\n");
printf(" Cladogram, Phenogram, curVogram, Eurogram,");
printf(" or Swoopogram\n");
printf(" (C, P, V, E, or S)\n");
do {
printf(" Choose one: \n");
scanf("%c%*[^\n]", &ch);
trash=getchar();
uppercase(&ch);
} while (ch != 'C' && ch != 'P' && ch != 'V' && ch != 'E' && ch != 'S');
switch (ch) {
case 'C':
style = cladogram;
break;
case 'P':
style = phenogram;
break;
case 'E':
style = eurogram;
break;
case 'S':
style = swoopogram;
break;
case 'V':
style = curvogram;
break;
}
break;
case 3:
if (haslengths) {
uselengths = !uselengths;
if (!uselengths)
nodeposition = vshaped;
else
nodeposition = intermediate;
} else {
printf("Cannot use lengths since not all of them exist\n");
uselengths = false;
}
break;
case 4:
printf("\n(Considering the tree as if it \"grew\" vertically:)\n");
printf("Are the labels to be plotted vertically (90),\n");
printf(" horizontally (0), or at a 45-degree angle?\n");
do {
printf(" Choose an angle in degrees from 90 to 0:\n");
scanf("%lf%*[^\n]", &labelrotation);
trash=getchar();
uppercase(&ch);
} while (labelrotation < 0.0 && labelrotation > 90.0);
break;
case 5:
printf("\nThe tree will be drawn to fit in a rectangle which has \n");
printf(" margins in the horizontal and vertical directions of:\n");
if (plotter == ray)
printf("%6.2f pixels (horizontal margin) and%6.2f pixels (vertical margin)\n",
xmargin, ymargin);
else
printf("%6.2f cm (horizontal margin) and%6.2f cm (vertical margin)\n",
xmargin, ymargin);
putchar('\n');
do {
if (plotter == ray)
printf(" New value (in pixels) of horizontal margin?\n");
else
printf(" New value (in cm) of horizontal margin?\n");
scanf("%lf%*[^\n]", &xmargin);
trash=getchar();
ok = ((unsigned)xmargin < xsize / 2.0);
if (!ok)
printf(" Impossible value. Please retype it.\n");
} while (!ok);
do {
if (plotter == ray)
printf(" New value (in pixels) of vertical margin?\n");
else
printf(" New value (in cm) of vertical margin?\n");
scanf("%lf%*[^\n]", &ymargin);
trash=getchar();
ok = ((unsigned)ymargin < ysize / 2.0);
if (!ok)
printf(" Impossible value. Please retype it.\n");
} while (!ok);
break;
case 6:
rescaled = !rescaled;
if (!rescaled) {
printf("Centimeters per unit branch length?\n");
scanf("%lf%*[^\n]", &bscale);
trash=getchar();
}
break;
case 7:
printf("New value of depth of tree as fraction of its breadth?\n");
scanf("%lf%*[^\n]", &treedepth);
trash=getchar();
break;
case 8:
do {
printf("New value of stem length as fraction of tree depth?\n");
scanf("%lf%*[^\n]", &stemlength);
trash=getchar();
} while ((unsigned)stemlength >= 0.9);
break;
case 9:
printf("New value of character height as fraction of tip spacing?\n");
scanf("%lf%*[^\n]", &nodespace);
trash=getchar();
nodespace = 1.0 / nodespace;
break;
case 10:
printf("Should interior node positions:\n");
printf(" be Intermediate between their immediate descendants,\n");
printf(" Weighted average of tip positions\n");
printf(" Centered among their ultimate descendants\n");
printf(" iNnermost of immediate descendants\n");
printf(" or so that tree is V-shaped\n");
do {
printf(" (type I, W, C, N or V):\n");
scanf("%c%*[^\n]", &ch);
trash=getchar();
uppercase(&ch);
} while (ch != 'I' && ch != 'W' && ch != 'C' && ch != 'N' && ch != 'V');
switch (ch) {
case 'W':
nodeposition = weighted;
break;
case 'I':
nodeposition = intermediate;
break;
case 'C':
nodeposition = centered;
break;
case 'N':
nodeposition = inner;
break;
case 'V':
nodeposition = vshaped;
break;
}
break;
case 11:
printf("Enter font name or \"Hershey\" for the default font\n");
gets(fontname);
break;
}
} /* getparms */
void calctraverse(p, lengthsum,tipx)
node *p;
double lengthsum;
double *tipx;
{
/* traverse to establish initial node coordinates */
double x1, y1, x2, y2, x3, w1, w2, sumwx, sumw, nodeheight, rr;
node *pp, *plast;
if (p == root)
nodeheight = 0.0;
else if (uselengths)
nodeheight = lengthsum + p->oldlen;
else
nodeheight = 1.0;
if (nodeheight > maxheight)
maxheight = nodeheight;
if (p->tip) {
p->xcoord = *tipx;
if (uselengths)
p->ycoord = nodeheight;
else
p->ycoord = 1.0;
*tipx += tipspacing;
return;
}
sumwx = 0.0;
sumw = 0.0;
pp = p->next;
x3 = 0.0;
do {
calctraverse(pp->back, nodeheight,tipx);
sumw += pp->back->tipsabove;
sumwx += pp->back->tipsabove * pp->back->xcoord;
if (fabs(pp->back->xcoord - 0.5) < fabs(x3 - 0.5))
x3 = pp->back->xcoord;
plast = pp;
pp = pp->next;
} while (pp != p);
x1 = p->next->back->xcoord;
x2 = plast->back->xcoord;
y1 = p->next->back->ycoord;
y2 = plast->back->ycoord;
rr = 2 * (1.0 - stemlength) * treedepth * maxheight;
switch (nodeposition) {
case weighted:
w1 = y1 - nodeheight;
w2 = y2 - nodeheight;
if (w1 + w2 <= 0.0)
p->xcoord = (x1 + x2) / 2.0;
else
p->xcoord = (w2 * x1 + w1 * x2) / (w1 + w2);
break;
case intermediate:
p->xcoord = (x1 + x2) / 2.0;
break;
case centered:
p->xcoord = sumwx / sumw;
break;
case inner:
p->xcoord = x3;
break;
case vshaped:
p->xcoord = (x1 + x2 + (y1 - y2) / rr) / 2.0;
break;
}
if (uselengths) {
p->ycoord = nodeheight;
return;
}
if (nodeposition != inner) {
p->ycoord = (y1 + y2 - sqrt((y1 + y2) * (y1 + y2) - 4 * (y1 * y2 -
rr * rr * (x2 - p->xcoord) * (p->xcoord - x1)))) / 2.0;
return;
}
if (fabs(x1 - 0.5) > fabs(x2 - 0.5)) {
p->ycoord = y1 + x1 - x2;
w1 = y2 - p->ycoord;
} else {
p->ycoord = y2 + x1 - x2;
w1 = y1 - p->ycoord;
}
if (w1 < epsilon)
p->ycoord -= fabs(x1 - x2);
} /* calctraverse */
void calculate()
{
/* compute coordinates for tree */
double tipx;
double sum, maxtextlength, textlength, firstlet, fontheight, angle;
long i;
for (i = 0; i < nextnode; i++)
nodep[i]->xcoord = 0.0;
for (i = 0; i < nextnode; i++)
nodep[i]->ycoord = 0.0;
maxheight = 0.0;
maxtextlength = 0.0;
if (nodep[0]->naymlength > 0)
firstlet = lengthtext(nodep[0]->nayme, 1L,font);
else
firstlet = 0.0;
sum = 0.0;
tipx = 0.0;
for (i = 0; i < nextnode; i++) {
if (nodep[i]->tip) {
textlength = lengthtext(nodep[i]->nayme, nodep[i]->naymlength,font);
if (textlength > maxtextlength)
maxtextlength = textlength;
}
}
fontheight = font[2];
angle = pi * labelrotation / 180.0;
maxtextlength /= fontheight;
textlength /= fontheight;
firstlet /= fontheight;
if (ntips > 1)
labelheight = 1.0 / (nodespace * (ntips - 1));
else
labelheight = 1.0 / nodespace;
if (angle < pi / 6.0)
tipspacing = (nodespace + cos(angle) * (maxtextlength - 0.5)) * labelheight;
else if (ntips > 1)
tipspacing = 1.0 / (ntips - 1.0);
else
tipspacing = 1.0;
topoflabels = labelheight *
(1.0 + sin(angle) * (maxtextlength - 0.5) + cos(angle) * 0.5);
rightoflabels = labelheight *
(cos(angle) * (textlength - 0.5) + sin(angle) * 0.5);
leftoflabels = labelheight * (cos(angle) * firstlet * 0.5 + sin(angle) * 0.5);
calctraverse(root, sum, &tipx);
rooty = root->ycoord;
for (i = 0; i < nextnode; i++) {
if (rescaled) {
nodep[i]->xcoord *= 1.0 - stemlength;
nodep[i]->ycoord = stemlength * treedepth + (1.0 - stemlength) *
treedepth * (nodep[i]->ycoord - rooty) / (maxheight - rooty);
} else {
nodep[i]->xcoord = nodep[i]->xcoord * (maxheight - rooty) / treedepth;
nodep[i]->ycoord = stemlength / (1 - stemlength) * (maxheight - rooty) +
nodep[i]->ycoord;
}
}
rooty = 0.0;
} /* calculate */
void rescale()
{
/* compute coordinates of tree for plot or preview device */
long i;
double treeheight, treewidth, extrax, extray, temp;
treeheight = 0.0;
for (i = 0; i < nextnode; i++) {
if (nodep[i]->ycoord > treeheight)
treeheight = nodep[i]->ycoord;
}
treewidth = (ntips - 1) * tipspacing + rightoflabels + leftoflabels;
if (rescaled) {
leftoflabels *= 1.0 - stemlength;
rightoflabels *= 1.0 - stemlength;
treewidth *= 1.0 - stemlength;
} else {
if (uselengths) {
labelheight = labelheight * (maxheight - rooty) / treedepth;
topoflabels = topoflabels * (maxheight - rooty) / treedepth;
leftoflabels = leftoflabels * (maxheight - rooty) / treedepth;
rightoflabels = rightoflabels * (maxheight - rooty) / treedepth;
treewidth = treewidth * (maxheight - rooty) / treedepth;
}
}
treeheight += topoflabels;
if (grows == vertical) {
if (!rescaled)
expand = bscale;
else {
expand = (xsize - 2 * xmargin) / treewidth;
if ((ysize - 2 * ymargin) / treeheight < expand)
expand = (ysize - 2 * ymargin) / treeheight;
}
extrax = (xsize - 2 * xmargin - treewidth * expand) / 2.0;
extray = (ysize - 2 * ymargin - treeheight * expand) / 2.0;
} else {
if (!rescaled)
expand = bscale;
else {
expand = (ysize - 2 * ymargin) / treewidth;
if ((xsize - 2 * xmargin) / treeheight < expand)
expand = (xsize - 2 * xmargin) / treeheight;
}
extrax = (xsize - 2 * xmargin - treeheight * expand) / 2.0;
extray = (ysize - 2 * ymargin - treewidth * expand) / 2.0;
}
for (i = 0; i < nextnode; i++) {
nodep[i]->xcoord = expand * (nodep[i]->xcoord + leftoflabels);
nodep[i]->ycoord = expand * (nodep[i]->ycoord - rooty);
if (grows == horizontal) {
temp = nodep[i]->ycoord;
nodep[i]->ycoord = expand * treewidth - nodep[i]->xcoord;
nodep[i]->xcoord = temp;
}
nodep[i]->xcoord += xmargin + extrax;
nodep[i]->ycoord += ymargin + extray;
}
if (grows == vertical)
rooty = ymargin + extray;
else
rooty = xmargin + extrax;
} /* rescale */
void plottree(p, q)
node *p, *q;
{
/* plot part or all of tree on the plotting device */
long i;
double x1, y1, x2, y2, x3, y3, f, g, h, fract, minny, miny;
node *pp;
x2 = xscale * (xoffset + p->xcoord);
y2 = yscale * (yoffset + p->ycoord);
if (p != root) {
x1 = xscale * (xoffset + q->xcoord);
y1 = yscale * (yoffset + q->ycoord);
plot(penup, x1, y1);
switch (style) {
case cladogram:
plot(pendown, x2, y2);
break;
case phenogram:
if (grows == vertical)
plot(pendown, x2, y1);
else
plot(pendown, x1, y2);
plot(pendown, x2, y2);
break;
case curvogram:
for (i = 1; i <= segments; i++) {
f = (double)i / segments;
g = (double)i / segments;
h = 1.0 - sqrt(1.0 - g * g);
if (grows == vertical) {
x3 = x1 * (1.0 - f) + x2 * f;
y3 = y1 + (y2 - y1) * h;
} else {
x3 = x1 + (x2 - x1) * h;
y3 = y1 * (1.0 - f) + y2 * f;
}
plot(pendown, x3, y3);
}
break;
case eurogram:
if (grows == vertical)
plot(pendown, x2, (2 * y1 + y2) / 3);
else
plot(pendown, (2 * x1 + x2) / 3, y2);
plot(pendown, x2, y2);
break;
case swoopogram:
if ((grows == vertical && fabs(y1 - y2) >= epsilon) ||
(grows == horizontal && fabs(x1 - x2) >= epsilon)) {
if (grows == vertical)
miny = p->ycoord;
else
miny = p->xcoord;
pp = q->next;
while (pp != q) {
if (grows == vertical)
minny = pp->back->ycoord;
else
minny = pp->back->xcoord;
if (minny < miny)
miny = minny;
pp = pp->next;
}
if (grows == vertical)
miny = yscale * (yoffset + miny);
else
miny = xscale * (xoffset + miny);
if (grows == vertical)
fract = 0.3333 * (miny - y1) / (y2 - y1);
else
fract = 0.3333 * (miny - x1) / (x2 - x1);
for (i = 1; i <= segments; i++) {
f = (double)i / segments;
if (f < fract)
g = f / fract;
else
g = (f - fract) / (1.0 - fract);
if (f < fract)
h = fract * sqrt(1.0 - (1.0 - g) * (1.0 - g));
else
h = fract + (1.0 - fract) * (1.000001 - sqrt(1.000001 - g * g));
if (grows == vertical) {
x3 = x1 * (1.0 - f) + x2 * f;
y3 = y1 + (y2 - y1) * h;
} else {
x3 = x1 + (x2 - x1) * h;
y3 = y1 * (1.0 - f) + y2 * f;
}
plot(pendown, x3, y3);
}
}
break;
}
} else {
if (grows == vertical) {
x1 = xscale * (xoffset + p->xcoord);
y1 = yscale * (yoffset + rooty);
} else {
x1 = xscale * (xoffset + rooty);
y1 = yscale * (yoffset + p->ycoord);
}
plot(penup, x1, y1);
plot(pendown, x2, y2);
}
if (p->tip)
return;
pp = p->next;
while (pp != p) {
plottree(pp->back, p);
pp = pp->next;
}
} /* plottree */
void plotlabels(fontname)
char *fontname;
{
long i;
double compr, dx, dy, angle;
node *lp;
compr = xunitspercm / yunitspercm;
if (penchange == yes)
changepen(labelpen);
angle = labelrotation * pi / 180.0;
for (i = 0; i < (nextnode); i++) {
if (nodep[i]->tip) {
lp = nodep[i];
dx = labelheight * expand * -0.70710 * cos(angle + pi / 4.0);
dy = labelheight * expand * (1.0 - 0.70710 * sin(angle + pi / 4.0));
if (grows == vertical)
plottext(lp->nayme, lp->naymlength,
labelheight * expand * xscale / compr, compr,
xscale * (lp->xcoord + dx + xoffset),
yscale * (lp->ycoord + dy + yoffset),
-labelrotation, font,fontname);
else
plottext(lp->nayme, lp->naymlength, labelheight * expand * yscale,
compr, xscale * (lp->xcoord + dy + xoffset),
yscale * (lp->ycoord - dx + yoffset), 90.0 - labelrotation,
font,fontname);
}
}
if (penchange == yes)
changepen(treepen);
} /* plotlabels */
#ifdef CHILDAPP
void RealMain(int argc, char** argv)
#else
main(argc, argv)
long argc;
Char *argv[];
#endif
{
long i,n,stripedepth;
boolean canbeplotted;
#if defined(MAC) || defined(__MWERKS__)
OSErr retcode;
FInfo fndrinfo;
#ifdef MAC
macsetup("Drawgram","Preview");
#endif
#endif
#ifdef TURBOC
if ((registerbgidriver(EGAVGA_driver) <0) ||
(registerbgidriver(Herc_driver) <0) ||
(registerbgidriver(CGA_driver) <0)){
printf("Graphics error: %s ",grapherrormsg(graphresult()));
exit(-1);}
#endif
strcpy(fontname,"Hershey");
openfile(&plotfile,PLOTFILE,"w",argv[0],pltfilename);
openfile(&treefile,TREEFILE,"r",argv[0],NULL);
printf("DRAWGRAM from PHYLIP version %s\n",VERSION);
printf("Reading tree ... \n");
treeread();
printf("Tree has been read.\nLoading the font .... \n");
loadfont(font,argv[0]);
printf("Font loaded.\n");
previewing = false;
initialparms();
canbeplotted = false;
while (!canbeplotted) {
do {
n=showparms();
if (n != -1)
getparms(n);
} while (n != -1);
calculate();
rescale();
canbeplotted = true;
if (preview)
canbeplotted=plotpreview(fontname,&xoffset,&yoffset,&scale,ntips,root);
}
if (dotmatrix) {
stripedepth = allocstripe(stripe,(strpwide/8),
((long)(yunitspercm * ysize)));
strpdeep = stripedepth;
strpdiv = stripedepth;
}
previewing = false;
initplotter(ntips,fontname);
numlines = dotmatrix ? ((long)floor(yunitspercm * ysize + 0.5)/strpdeep) : 1;
if (plotter != ibmpc)
printf("Writing plot file ...\n");
drawit(fontname,&xoffset,&yoffset,numlines,root);
finishplotter();
FClose(plotfile);
FClose(treefile);
printf("Finished.\nEnd of run.\n");
#if defined(__MWERKS__)
if (plotter == pict){
retcode= getfinfo( PLOTFILE,0,&fndrinfo);
fndrinfo.fdType='PICT';
fndrinfo.fdCreator='MDRW';
retcode=setfinfo( PLOTFILE,0,&fndrinfo);
}
if (plotter == lw){
retcode=getfinfo( PLOTFILE,0,&fndrinfo);
fndrinfo.fdType='TEXT';
retcode=setfinfo( PLOTFILE,0,&fndrinfo);
}
#endif
#if defined(MAC)
if (plotter == pict){
retcode=GetFInfo(CtoPstr(PLOTFILE),0,&fndrinfo);
fndrinfo.fdType='PICT';
fndrinfo.fdCreator='MDRW';
retcode=SetFInfo(CtoPstr(PLOTFILE),0,&fndrinfo);}
if (plotter == lw){
retcode=GetFInfo(CtoPstr(PLOTFILE),0,&fndrinfo);
fndrinfo.fdType='TEXT';
retcode=SetFInfo(CtoPstr(PLOTFILE),0,&fndrinfo);}
#endif
exit(0);
}
int eof(f)
FILE *f;
{
register long ch;
if (feof(f))
return 1;
if (f == stdin)
return 0;
ch = getc(f);
if (ch == EOF)
return 1;
ungetc(ch, f);
return 0;
}
int eoln(f)
FILE *f;
{
register long ch;
ch = getc(f);
if (ch == EOF)
return 1;
ungetc(ch, f);
return (ch == '\n');
}
void memerror()
{
printf("Error allocating memory\n");
exit(-1);
}
MALLOCRETURN *mymalloc(x)
long x;
{
MALLOCRETURN *mem;
mem = (MALLOCRETURN *)malloc((size_t)x);
if (!mem)
memerror();
else
return (MALLOCRETURN *)mem;
}